home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / sorce.scr < prev    next >
Internet Message Format  |  1991-05-13  |  15KB

  1. From ervin@pinbot.enet.dec.com Fri May 10 15:35:00 1991
  2. Flags: 000000000001
  3. Received: from enet-gw.pa.dec.com by hpuxa.acs.ohio-state.edu with SMTP
  4.     (15.11/15.6) id AA08264; Fri, 10 May 91 13:34:42 edt
  5. Return-Path: <ervin@pinbot.enet.dec.com>
  6. Received: by enet-gw.pa.dec.com; id AA14061; Fri, 10 May 91 10:34:10 -0700
  7. Message-Id: <9105101734.AA14061@enet-gw.pa.dec.com>
  8. Received: from pinbot.enet; by decwrl.enet; Fri, 10 May 91 10:34:21 PDT
  9. Date: Fri, 10 May 91 10:34:21 PDT
  10. From: 10-May-1991 1331 <ervin@pinbot.enet.dec.com>
  11. To: ryee@hpuxa.acs.ohio-state.edu
  12. Subject: Re: HP48: Waynes mail server 
  13.  
  14. Hi Roger,
  15.  
  16. Here's another file that would be good for Wayne's mail server.  This is the
  17. source code to my screen dissolver.  The executable is currently in the
  18. graphics directory, so that's probably where this file should go as well.
  19.  
  20. How about a file description like "Source code for Joe Ervin's dissolver.".
  21.  
  22. Thanks again!
  23.  
  24. >>>Joe
  25.  
  26. ****************************************************************************
  27. ; DISSOLVE VERSION 0.2
  28. ; Joe Ervin - 4-MAR-1991
  29. ;
  30. ; The following program is written for the HP-48SX.  This program is intended
  31. ; to be assembled using the Star assembler, version 1.04.2 or later.
  32.  
  33. ; The purpose of this program is to provide a function which can be used to do
  34. ; screen dissolves.  In other words, this program will take a GROB from the
  35. ; stack and dissolve it into PICT, updating PICT with the pixels of the new
  36. ; GROB one pixel at a time, in a visually random sequence so that the visual 
  37. ; effect is that the image contained in the GROB dissolves into the display,
  38. ; replacing the existing image in PICT in an asthetically pleasing manner.
  39.  
  40.  
  41.  
  42. ; THEORY:
  43. ;
  44. ; The basic technique used to dissolve the screen will be to number the nibbles
  45. ; which make up the GROB sequentially, such that the nibbles which make up the
  46. ; first row of pixels start from the left with 1, 2, 3, and so on.  the rest 
  47. ; of the lines are numbered similarly.  In this way, all the nibbles that make
  48. ; up the GROB (and PICT) are numbered from 1 to n, where n is the last nibble 
  49. ; on the right end of the last row of pixels.
  50. ; The method used to generate the pixel addresses will be to use a simple 
  51. ; psuedo-random number generator formula.  There are many such formulae which 
  52. ; will generate all integers between 0 and 2^n exactly once (which is what
  53. ; we want here.  The formula I have chosen is a particularly simple one, and
  54. ; is given as : 
  55. ;
  56. ; next(r) = (r * 5) + 3.
  57. ;
  58. ; In our case, we will mask these random numbers to 14-bits.  We will use the
  59. ; bottom 2 bits of this random number to indicate which of the four pixels
  60. ; within each nibble we should transfer.  This allows us
  61. ; to randomly generate relative addresses for all the pixels in PICT (assuming
  62. ; that PICT is 131x64, as is usually the case). 
  63. ; Using this, we can successfully generate the address of every pixel in 
  64. ; PICT exactly once.  Of course, we will unavoidably generate addresses which 
  65. ; are outside the bounds of PICT (since the size of PICT is not an even power
  66. ; of 2).  Such addresses will simply be discarded. 
  67.  
  68. ; NOTES:    D0 is the RPL instruction pointer.
  69. ;             D1 is the stack pointer. Grows towards lower addresses.
  70. ;             B is the FRAME pointer. Grows towards higher addresses.
  71. ;             D is the amount of nibbles between stack and heap.
  72.  
  73. ; Each of the above registers may have a secondary use within the program.
  74.  
  75. ;            R0 holds the pointer to the dest GROB (PICT) data field.   
  76. ;         R1 holds the GROB size.
  77. ;        R2 holds a pointer to the source GROB data field.
  78. ;        R3 holds the 12 bit version of the random number.
  79. ;               R4 holds the 14/12 bit version of the random number.
  80. ;        D  holds the 14-bit mask.
  81. ;        B  holds the bit mask corresponding to the bit within the
  82. ;           nibble which is to be transfered.
  83.  
  84.     header            ; puts the kermit header at the top.
  85.  
  86.  
  87. ; Below is the internal RPL structure which will do error checking and which
  88. ; encapsulates the machine language routine.
  89. ; The RPL code expects the following parameters on the stack from the user.
  90. ; 2: A real number.  Zero indicates that a bit-wise dissolve should be 
  91. ;    performed.  A 1 indicates that tiling should be done.
  92. ; 1: Source GROB.
  93.  
  94.  
  95. ; The purpose of this RPL code is to do the argument
  96. ; type checking and build the proper parameters on the stack for the machine
  97. ; language code which does the actual screen dissolve.
  98.  
  99.  
  100.     badgrob = `Invalid GROB Data'
  101.     badgrobs = $((2 * sz^badgrob) + 5)    
  102.     badpict = `Invalid PICT Size'
  103.     badpicts = $((2 * sz^badpict) + 5)    
  104.  
  105.     radix    ^x10    ; Set the radix to hex.
  106.  
  107.     rpl        ; Start of RPL body.
  108.     2d9d        ; Start of program
  109.     1884d        ; Set last token to <0h>. 
  110.     18a8d        ; Check that there are at least 2 arguments on the stk.
  111.     18fb2        ; Check that the args are the right type.
  112.     4107        ; <1Ch>    2: real, 1: GROB.
  113.       2d9d        ; Start of program
  114.       3188        ; Internal DUP.
  115.  
  116. ; Now we need to check the size of the GROB to make sure it has the standard 
  117. ; size.
  118.       1ca62        ; Internal SIZE (graphic).
  119.       5a03        ; binary --> short
  120.       3223        ; Internal SWAP.
  121.       5a03        ; binary --> short
  122.       3223        ; Internal SWAP.
  123.             ; Now both dimensions of the grob are short binaries.
  124.       2911        ; System Binary
  125.       40        ; 64 decimal.
  126.       63d3a        ; If TOS-1 = TOS (Syst Bin), then skip next, else
  127.             ; do next and return.
  128.       2d9d        ; Start of program
  129.         3244    ; Internal DROP. Get rid of row dimension.
  130.         2A2C    ; String
  131.         _data.a badgrobs     ; length of the string.
  132.         _ascii badgrob
  133.         1a339        ; DOERR.
  134.         312b        ; end marker
  135.       2911        ; System Binary
  136.       83        ; 131 decimal.
  137.       63d3a        ; If TOS-1 = TOS (Syst Bin), then skip next, else
  138.             ; do next and return.
  139.       2d9d        ; Start of program
  140.         3244        ; Internal DROP. Get rid of row dimension.
  141.         2A2C        ; String
  142.         _data.a badgrobs     ; length of the string.
  143.         _ascii badgrob
  144.         1a339        ; DOERR.
  145.       312b        ; end marker
  146.  
  147. ; Now we need to check the size of PICT to make sure it has the standard size.
  148.       5187f        ; Get pict dimensions.
  149.       3223        ; Internal SWAP --> 2: columns, 1: rows.
  150.       2911        ; System Binary
  151.       40        ; 64 decimal.
  152.       63d3a        ; If TOS-1 = TOS (Syst Bin), then skip next, else
  153.             ; do next and return.
  154.       2d9d        ; Start of program
  155.         3244        ; Internal DROP. Get rid of row dimension.
  156.         2A2C        ; String
  157.         _data.a badpicts     ; length of the string.
  158.         _ascii badpict
  159.         1a339        ; DOERR.
  160.       312b        ; end marker
  161.       2911        ; System Binary
  162.       83        ; 131 decimal.
  163.       63d3a        ; If TOS-1 = TOS (Syst Bin), then skip next, else
  164.             ; do next and return.
  165.       2d9d        ; Start of program
  166.         3244        ; Internal DROP. Get rid of row dimension.
  167.         2A2C        ; String
  168.         _data.a badpicts     ; length of the string.
  169.         _ascii badpict
  170.         1a339        ; DOERR.
  171.       312b        ; end marker
  172.       3223        ; Internal SWAP. Put the "real" at level 1.
  173.       18cea        ; Convert real to system binary.
  174.       2911        ; System Binary; the size-1 of PICT in nibbles.
  175.       ^d2175        ; 2175 decimal. 
  176.       3223        ; Internal SWAP.
  177.     endrpl
  178.  
  179. ;*************************************************************************
  180. ; The machine language portion of DISS starts here.
  181.  
  182.  
  183.         radix ^d10    ; set default radix to decimal
  184.  
  185.     code        ; START OF MACHINE LANGUAGE ROUTINE.
  186.  
  187.  
  188. ; Addresses of ROM routines.
  189.  
  190.     save_registers    =    ^x679B    ; Saves system registers.    
  191.     restore_registers =     ^x67d2  ; Restores system register.
  192.     rplcont        =     ^x71BE  ; Jumps to the next RPL instruction.
  193.     rr_rplcont    =    ^x5143  ; Restores the system registers and
  194.                     ; then does rplcont.
  195.     get_short    =     ^x6641    ; Pops the short of TOS and returns it
  196.                     ; into A.A
  197.  
  198.  
  199. ; General address definitions
  200.     bos        =     ^x7057E    ; Pointer to beginning of the stack.
  201.     pict_pointer    =    ^x70565    ; Pointer to PICT grob.
  202.  
  203.  
  204. START:    
  205.  
  206.  
  207.  
  208.  
  209. ; The first thing we need to do is to get the input parameters off the stack.
  210. ; The parameters that this routine expects on the stack are:
  211.   
  212. ; 3:  Source GROB (the one which will be on display at end of routine.)
  213. ; 2:  System binary integer (short) indicating the number of nibbles to move.
  214. ; 1:  System binary integer (short) indicating #0 for bit-wise dissolve, or 
  215. ;     #(nonzero) for tiling.
  216.  
  217.  
  218.     CALL.A get_short    ; Put the tile/dissolve indicator in A.A
  219.             ; If this integer is a zero, then we
  220.             ; do bit-wise dissolve.  If non-zero, we do nibble
  221.             ; tiling.
  222.     CLR.W    D    ; Clear every bit in D.
  223.     BRZ.A    A, DISSOLVE    ; If zero, then leave D.S clear for (dissolve).
  224.                 ; Otherwise, set D.S = 1 (for tiling).
  225. TILING:    INC.S    D    ; Set D.S to 1 (nonzero is all that matters).
  226.             ; This field will be tested later.
  227. DISSOLVE:    
  228.     CALL.A get_short    ; Get the level 2 system binary off the stack into A.A.
  229.             ; This is the GROB size-1.
  230.     CLR.W    C    ;
  231.     SWAP.A    A, C    ; 
  232.     MOVE.W    C, R1    ; Save it in R1.
  233.  
  234.  
  235. ; Then we get the pointer to the source GROB data and load it into R2.
  236.  
  237.     MOVE.A     @D1, A    ; Gets the address of the level 3 object.
  238.     ADD.A    10, A    ; Skip over the prolog and size fields.
  239.     ADD.A    10, A    ; Skip over the row and column fields of the GROB.
  240.     MOVE.A    A, R2    ; Save pointer to GROB data in R2.
  241.  
  242.     ADD.A    5, D1    ; to pop the level 3 object off the stack...
  243.     INC.A    D    ; and increment the free size counter.
  244.  
  245.  
  246.  
  247.  
  248.     CALL.A    save_registers    ; Save the system registers.
  249.  
  250. ; At this point, we have saved all the information we need to start the loop
  251. ; which calculates all the screen addresses randomly. 
  252.  
  253.  
  254. ; The following psuedocode represents essentially what this code does:
  255.  
  256.  
  257. ; BEGIN
  258. ;   R = 0
  259. ;   TRANSFER_PIXEL(R[BITMASK]);
  260. ;   DO
  261. ;     R = RANDOM(R)
  262. ;     IF R <= GROB_SIZE THEN TRANSFER_PIXEL(R[BITMASK])
  263. ;   UNTIL R = 0
  264. ; END;
  265.  
  266.  
  267.  
  268. ; We need to fetch the address of the beginning of the data field of PICT.
  269.  
  270.     MOVE.A     pict_pointer, D1    ; Address which contains pointer to 
  271.                     ; display.
  272.     MOVE.A    @D1, C    ; get the address of PICT GROB.
  273.     ADD.A    10, C    ; Skip over the prolog and size fields.
  274.     ADD.A    10, C    ; Skip over the row and column size fields.
  275.     MOVE.A    C, R0    ; Copy pointer to PICT data field in R0 for later use.
  276.  
  277. ; We need to initialize the mask held in D to ^x3FFF if doing a bit-wise 
  278. ; dissolve or to ^xFFF if tiling.
  279.  
  280.     CLR.W    C    ; 
  281.     MOVE.P5    ^x3FFF, C    ; Puts 14 ones in the lower bit positions of C,
  282.     BRZ.S    D, DISSOLVE2    ; Tiling or bit-wise dissolve?
  283.     MOVE.P5 ^xFFF, C    ; Change the mask to 12 bits for tiling.
  284. DISSOLVE2:    MOVE.A    C, D    ; and transfer it to D.
  285.  
  286.  
  287.     CLR.W    A    ;
  288.     MOVE.W    A, R3    ; Initialize the random value to 0.
  289.     MOVE.W    A, R4    ; Note: because of the really cool properties of the
  290.             ; algorithm used here, the value 0 will not repeat 
  291.             ; until every other integer has been created.  
  292.             ; Note that if doing tiling we use a 12-bit integer,
  293.             ; and if dissolving, we use a 14-bit integer.
  294.     
  295.     CLR.W    C
  296.     MOVE.P2 ^x11, C    ; Indicates the first bit for dissolve.
  297.     BRZ.S    D, DISSOLVE3    ; Tiling or bit-wise dissolve?
  298.     MOVE.P2 ^x0F, C    ; Change the bit pattern to ^xF if tiling.
  299. DISSOLVE3:    MOVE.B    C, B    
  300.  
  301. ; The bottom nibble of B holds the bit mask which indicates which 
  302. ; bit(s) in the nibble we are transfering.  If we are dissolving, then only 
  303. ; 1 bit of this nibble is set.  If tiling, then this nibble contains ^xF to 
  304. ; indicate that all four bits within the nibble should be transfered at once.
  305.  
  306. ; Now we must transfer a pixel of data at the
  307. ; Rth nibble of the stack GROB to the PICT GROB.  The bit within the nibble
  308. ; that will be transfered is indicated by the BITMASK variable.
  309.  
  310.     MOVE.A    R3, A    ; Get the random number.
  311.     CALL    TRANSFER_GROB    ; Transfer the GROB data pointed to by A.A.
  312.  
  313.     
  314. DO:    ; Begin the loop.
  315.  
  316.     MOVE.W    R4, C    ; Get the 14/12-bit version of the random number R. 
  317.     ADD.A    C, C    ; 
  318.     ADD.A    C, C    ;
  319.     MOVE.W    R4, A    ;
  320.     ADD.A    A, C    ; Multiply R by 5,...
  321.     ADD.A    3, C    ; ....and add 3.
  322.     AND.A    D, C    ; Mask off everything but the lower 14/12-bits.
  323.     MOVE.A    C, R4    ; Temporary storage for 14/12-bit version.  This
  324.             ; 14/12 bit number is compared to 0 to see if the 
  325.             ; random number generator has finished its cycle.
  326.     MOVE.A    C, R3    ; This is for the case of tiling.  If dissolving, this
  327.             ; will be overwritten below.
  328.     BRNZ.S    D, P_TRANS    ; Tiling or dissolving? If tiling, then we can
  329.                 ; leave B containing ^xF.
  330.     SRB.A    C
  331.     SRB.A    C       ; Shift the bottom two bits out, yielding a 12-bit #.
  332.     MOVE.A    C, R3    ; Save the 12-bit random number in R3. This copy of 
  333.             ; the random number R is always 12-bits, and is used
  334.             ; by the code which transfers the GROB data to index
  335.             ; into the GROB.
  336.     SRB.B    B    ; Shift the mask one bit to the right to point to the
  337.             ; next bit to be tranfered.  This works because the
  338.             ; the random number generator used here cycles the 
  339.             ; botom 2 bits through 3, 2, 1, 0, 3, 2, 1, 0, etc.
  340.             ; Therefore, we just drop them and rotate the bit mask.
  341.     MOVE.B    B, A    ; Get copy of bit mask.
  342.     BRBC    3, A, P_TRANS    ; If bit mask is OK, skip to P_TRANS.
  343.     SETB    7, A    ; Else, insert a 1 in bit 7 to keep the rotating bit 
  344.             ; mask working properly.
  345.     MOVE.B    A, B    ; Restore new bit mask.
  346.  
  347. P_TRANS:
  348.  
  349.     MOVE.A  R1, A    ; Get the GROB size.
  350.     MOVE.A    R3, C    ; Get the 12-bit version of the random number. This 
  351.             ; will be used below as an index into the source GROB.
  352.     BRGT.A    C, A, SKIP    ; IF R is greater than the GROB size, then 
  353.                 ; skip it.
  354.         
  355.     SWAP.A A, C    ; Put the GROB offset in A.A. Required by the procedure
  356.             ; TRANSFER_GROB.
  357.     CALL    TRANSFER_GROB    ; Transfer a pixel or nibble of data from the
  358.                 ; source GROB to PICT.
  359.  
  360.  
  361. SKIP:    ; We came here because the generated random number was outside the 
  362.     ; range of addresses in the GROB.
  363.  
  364.     MOVE.A    R4, A    ; Get the value of R most recently generated.
  365.         BRNZ.A    A, DO    ; If the last value of R is zero, then we have finished
  366.             ; generating all the addresses, and have finished this
  367.             ; pass. Otherwise, we must branch up and keep
  368.             ; generating more random values.
  369.  
  370.  
  371. ; Now to restore things to a sane state before returning control to the calling
  372. ; RPL program.
  373.  
  374.  
  375.  
  376. DONE:   JUMP rr_rplcont ; Restore the system registers...
  377.             ; and continue on with the RPL thread.
  378.  
  379. TRANSFER_GROB:            ; Routine that transfers GROB data from the source
  380.             ; GROB to PICT.
  381.  
  382.     MOVE.A    R2, C    ; Get the pointer to the GROB data.
  383.     ADD.A    A, C    ; Add the offset (R)
  384.     MOVE.A    C, D1    ; Point to nibble in stack GROB to be read.
  385.     CLR.W    A    ; Zero out A.
  386.     MOVE.B    @D1, A    ; Get the nibble from the GROB into A.
  387.  
  388. ; Now what I need to do is GROB*MASK+PICT*MASK_BAR  ---> PICT.
  389.  
  390.     AND.B    B, A    ; Perform bit-AND of BITMASK and nibble from GROB.
  391.             ; This value will be ORd with the same nibble from
  392.             ; PICT and written back into PICT, thus moving the bit
  393.             ; from the stack GROB to PICT.
  394.  
  395.     MOVE.W    R3, C    ; Get the pointer into the GROB.
  396.  
  397. ; At this point, the modified nibble from stack GROB is in A.  
  398. ;         the offset into PICT is in C.
  399.  
  400.     SWAP.A    A, D1    ; Save the nibble in A into D1 for a moment.
  401.     MOVE.A    R0, A    ; Get the address of PICT.
  402.     ADD.A    A, C    ; Now C contains the address of the nibble in PICT.
  403.     SWAP.A    A, D1    ; Restore the nibble from the source GROB into A.
  404.     MOVE.A    C, D1    ; Point into PICT.
  405.     MOVE.B    @D1, C    ; Get the nibble from PICT.
  406.     NOT.B    B    ; Invert the mask for a moment.
  407.     AND.B    B, C    ; Mask off the bits to be modified.
  408.     OR.B    A, C    ; Modify the BITMASKth bit in the nibble,....
  409.     NOT.B    B    ; restore the mask to its original state.
  410.     MOVE.1    C, @D1    ; and write it back into PICT.
  411.     RET
  412.  
  413.     endcode
  414.  
  415.     radix ^x10    ; Go back to hex.
  416.      RPL
  417.     312b        ; end marker.
  418.     312b        ; End program object
  419.     ENDRPL
  420.  
  421. end
  422.  
  423.